package com.lgl.scs.util.utils;

import com.github.pagehelper.PageInfo;
import com.lgl.scs.information.service.AddressService;
import com.lgl.scs.mobile.service.MServiceOrderService;
import com.lgl.scs.userIndex.service.AppUserService;
import com.lgl.scs.util.service.UtilService;
import com.lgl.scs.wx.service.WxServiceOrderService;
import com.lgl.scs.wx.service.WxUserService;
import com.lgl.scsapi.system.model.AppUser;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.system.model.ServiceOrder;
import com.lgl.scsapi.util.utils.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信端跟电脑端部分代码逻辑相同，此类为controller的代码利用公共类
 */
@Slf4j
public class ControllerUtil {

    /**
     * 校验用户登录结果
     * @return
     */
    public static Map<String, String> checkUserLoginResult(PageData paramPd, Object userService, UtilService utilService){
        Map<String, String> checkUserMap = new HashMap<String, String>(4);
        String userName = paramPd.getString("userName");
        String userPassword = paramPd.getString("userPassword");
        if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(userPassword)){
            checkUserMap.put("status", "1");
            return checkUserMap;
        }
        String hashPassword = new SimpleHash(Constants.ALGORITHM_NAME,userPassword, Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
        paramPd.put("userName", userName);
        paramPd.put("userPassword", hashPassword);
        AppUser user = null;
        if (userService instanceof AppUserService){
            AppUserService appUserService = (AppUserService)userService;
            user = appUserService.findByNameAndPassword(paramPd);
        }else if (userService instanceof WxUserService){
            WxUserService wxUserService = (WxUserService)userService;
            user = wxUserService.findByNameAndPassword(paramPd);
        }
        if(user == null){
            checkUserMap.put("status", "3");
            return checkUserMap;
        }
        user.setUserName(userName).setPassword(userPassword);
        return checkAndLoginUser(user,checkUserMap,utilService);
    }

    /**
     * 判断用户是否存在，并执行登录
     * @param user 登录/注册用户
     * @param checkUserMap 校验的部分参数
     * @return 返回校验后的结果
     */
    public static Map<String,String> checkAndLoginUser(AppUser user,Map<String, String> checkUserMap,UtilService utilService){
        if(user == null){
            checkUserMap.put("status", "3");
            return checkUserMap;
        }
        //用户已冻结
        if("1".equals(user.getStatus())){
            checkUserMap.put("status", "5");
            return checkUserMap;
        }
        checkUserMap.put("status", "0");//验证成功
        checkUserMap.put("userPhone", user.getPhone() == null ? "" : user.getPhone());
        checkUserMap.put("userId", user.getUserId());
        checkUserMap.put("userName", user.getUserName());
        checkUserMap.put("nickName", user.getNickName());
        checkUserMap.put("sex", String.valueOf(user.getSex()));
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());
        try {
            subject.login(token);
            //清空缓存中的用户密码，以减少密码占用缓存空间
            user.setPassword(null);
            subject.getSession().setAttribute(Constants.SESSION_USER, user);
            utilService.asyncSetLoginStatus(user.getUserId());
        } catch (AuthenticationException e) {
            checkUserMap.put("status", "4");
            log.error(e.toString(),e);
        }
        return checkUserMap;
    }

    /**
     * 初始化区域编码和服务类型参数
     * @param pd
     */
    public static void initAreaCodeAndServiceType(PageData pd) {
        Object soAreaCodeObj = pd.remove("soAreaCodes"), soServiceTypeIdObj = pd.remove("soServiceTypeIds");
        if (soAreaCodeObj != null && StringUtils.hasText(soAreaCodeObj.toString())) {
            String soAreaCodes = soAreaCodeObj.toString();
            //如果前台传多个区域编码
            if (soAreaCodes.contains(",")) {
                pd.put("soAreaCodeArray", soAreaCodes.split(","));
            }else {
                pd.put("soAreaCode", soAreaCodes);
            }
        }
        if (soServiceTypeIdObj != null && StringUtils.hasText(soServiceTypeIdObj.toString())) {
            String soServiceTypeIds = soServiceTypeIdObj.toString();
            //如果前台传多个服务类型ID
            if (soServiceTypeIds.contains(",")) {
                pd.put("serviceTypeArray", soServiceTypeIds);
            }else {
                pd.put("serviceTypeId", soServiceTypeIds);
            }
        }
    }

    /**
     * 通过城市名称获取城市编码
     * @param serviceOrder 订单对象
     * @param addressService 地址service
     * @return 城市编码
     */
    public static String getCityCodeByName(ServiceOrder serviceOrder, AddressService addressService){
        String cityName = serviceOrder.getCityName(), soCityCode = null;
        if (StringUtils.hasText(cityName)) {
            if (cityName.endsWith("市")){
                cityName = cityName.substring(0, cityName.length() - 1);
            }
            //从热门城市集合中通过城市名获取城市编码
            soCityCode = Constants.hotCityMap.get(cityName);
            if (!StringUtils.hasText(soCityCode)) {
                //从数据库中通过城市名获取城市编码
                soCityCode = addressService.findCityIdByName(cityName);
            }
        }
        if (StringUtils.hasText(soCityCode)){
            return soCityCode;
        }
        String areaCode = serviceOrder.getSoAreaCode();
        if (StringUtils.hasText(areaCode)){
            soCityCode = addressService.findCityCodeByAreaCode(areaCode);
        }
        return soCityCode;
    }

    /**
     * 获取订单分页数据
     * @param loginUser 登录用户
     * @param pagePd 订单相关参数
     * @param addressService 地址service
     * @param orderService 订单service
     * @return 订单分页数据PageInfo对象
     */
    public static PageInfo pageOrder(AppUser loginUser,PageData pagePd,AddressService addressService,Object orderService){
        int pageSize = Integer.parseInt(pagePd.remove("showCount").toString()),
                pageNo = Integer.parseInt(pagePd.remove("currentPage").toString());
        //取得城市编码
        String cityCode = pagePd.getString("cityCode"), cityName = pagePd.getString("cityName");
        if (!StringUtils.hasText(cityCode)) {
            cityCode = Constants.hotCityMap.get(cityName);
            if (!StringUtils.hasText(cityCode)) {
                cityCode = addressService.findCityIdByName(cityName);
            }
        }
        initAreaCodeAndServiceType(pagePd);
        pagePd.put("cityCode", cityCode);
        pagePd.put("soStatus", "0");
        if (loginUser != null){
            //如果当前用户已登录，则在主页上不显示用户自己发布的订单
            pagePd.put("notEqualsUser",loginUser.getUserId());
        }
        PageInfo mPageInfo = null;
        if (orderService instanceof MServiceOrderService){
            MServiceOrderService mServiceOrderService = (MServiceOrderService)orderService;
            mPageInfo = mServiceOrderService.mPageServiceOrder(pageNo,pageSize,pagePd);
        }else if (orderService instanceof WxServiceOrderService){
            WxServiceOrderService wxOrderService = (WxServiceOrderService)orderService;
            mPageInfo = wxOrderService.wxIndexPageOrder(pageNo,pageSize,pagePd);
        }
        return mPageInfo;
    }
}
